package com.rsk.api;


import io.swagger.annotations.ApiOperation;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.QueryParam;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;
import com.rsk.aop.ParamCheck;
import com.rsk.redis.RedisUtils;
import com.rsk.service.SysUserService;
import com.rsk.shiro.common.ShiroConst;
import com.rsk.shiro.jwt.JwtUtil;
import com.rsk.utils.algorithm.RSAUtils;
import com.rsk.utils.common.CommonConst;
import com.rsk.utils.json.JsonUtils;
import com.rsk.utils.result.Result;
import com.rsk.utils.result.ResultBuilder;
import com.rsk.utils.result.ResultCode;



@RestController
public class LoginApi{
	
	private static final Logger logger = LoggerFactory.getLogger(LoginApi.class);
	
	@Reference(interfaceClass = SysUserService.class, protocol = "dubbo")
	private SysUserService sysUserService;
	
    @Autowired
    private RedisUtils redisUtils;
	
	@PostMapping(value="/login" )
    public Result<String> login(@QueryParam("account") String account,
								@QueryParam("passWord") @ParamCheck(length={1,5}) String passWord) throws NoSuchAlgorithmException, InvalidKeySpecException{
		// 查询数据库中的帐号信息
		Map<String, String> map = sysUserService.login(account);
		if(map.isEmpty()){
			logger.error("该帐号不存在(The account does not exist.)");
			return ResultBuilder.successNoData(ResultCode.USER_NOT_EXIST);
		}
		//RSA解密
		String key = RSAUtils.privateDecrypt(map.get("password"), RSAUtils.getPrivateKey(CommonConst.encryptRSAPrivateKey));
        // 因为密码加密是以帐号+密码的形式进行加密的，所以解密后的对比是帐号+密码
        if (key.equals(account + passWord)) {
            // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
        	long nowTiem = System.currentTimeMillis();
            // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
            String token = JwtUtil.sign(account, nowTiem);
            // 清除可能存在的Shiro权限信息缓存
            String tokenKey = ShiroConst.shiro_redis + account;
            if (redisUtils.hasKey(tokenKey)) {
            	redisUtils.del(tokenKey);
            }
            //更新RefreshToken缓存的时间戳
            String refreshTokenKey= ShiroConst.shiro_refresh + account;
            if (redisUtils.hasKey(refreshTokenKey)) {
            	redisUtils.set(refreshTokenKey, String.valueOf(nowTiem), ShiroConst.refreshTokenExpireTime);
            }else{
            	redisUtils.set(refreshTokenKey, String.valueOf(nowTiem), ShiroConst.refreshTokenExpireTime);
            }
            //获取用户权限
            Map<String, Object> returnMap = new HashMap<String, Object>();
            returnMap.put("token",token);
            return ResultBuilder.success(JsonUtils.objectToJson(returnMap), ResultCode.USER_LOGIN_SUCCESS);
        } else {
        	logger.error("帐号或密码错误(Account or Password Error.)");
        	return ResultBuilder.faile(ResultCode.USER_LOGIN_ERROR);
        }
    }
}
